#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <math.h>
#include <stdint.h>
#include <rtthread.h>
#include "stm32f4xx.h"
#include "sys_timer.h"
#include "tools.h"

#define SYMBOL_GLOBALS
#include "sys_timer.h"
#undef SYMBOL_GLOBALS

static volatile uint32_t lo_unElapsedSecs, lo_unElapsedMSecs, lo_unCurSysticks;

static uint8_t lo_ubSysticksOfOneUS = 0;						//* 1微秒多少个时钟节拍
static uint8_t lo_ubMillisecondsOfOneSystick = 0;		//* 一个时钟节拍多少毫秒
 
extern void rt_interrupt_enter(void); 
extern void rt_interrupt_leave(void); 
extern void rt_tick_increase(void); 

//* systick中断服务函数,使用ucos时用到
void SysTick_Handler(void)
{	
  rt_interrupt_enter(); 
  {
    rt_tick_increase(); 
  
    lo_unCurSysticks++;
    lo_unElapsedMSecs += lo_ubMillisecondsOfOneSystick;
    
    if(!(lo_unCurSysticks % RT_TICK_PER_SECOND))    
      lo_unElapsedSecs++;                 
  }  
	rt_interrupt_leave(); 
}
			   
void OSSystimerInit(void)
{		
  RCC_ClocksTypeDef stClocks;
  
	lo_ubSysticksOfOneUS = SystemCoreClock / 1000000; 
	lo_ubMillisecondsOfOneSystick = 1000 / RT_TICK_PER_SECOND;	//* 代表OS可以延时的最小单位	   	
	lo_unElapsedSecs  = 0; 
	lo_unElapsedMSecs = 0; 
	lo_unCurSysticks  = 0;  
  
  RCC_GetClocksFreq(&stClocks);
  SysTick_Config(stClocks.SYSCLK_Frequency / RT_TICK_PER_SECOND - 1);
  NVIC_SetPriority (SysTick_IRQn, 1);  
}								    

void delay_us(uint32_t unDelayUS)
{		
	uint32_t unTicks;
	uint32_t unOldTime, unNowTime, unTimeCnt = 0;
	uint32_t unReload = SysTick->LOAD; //* 当前计数值
	
	unTicks   = unDelayUS * lo_ubSysticksOfOneUS; //* 需要的节拍数
	unTimeCnt = 0;
	rt_enter_critical();
	{
		unOldTime = SysTick->VAL; //* 此时的计数值
		while(TRUE)
		{
			unNowTime = SysTick->VAL;
			if(unNowTime != unOldTime)
			{
				if(unNowTime < unOldTime)
					unTimeCnt += unOldTime - unNowTime;
				else 
					unTimeCnt += unReload - unNowTime + unOldTime;	
				
				unOldTime = unNowTime;
				if(unTimeCnt >= unTicks)	//* 延时到达
					break;
			}
		}
	}
	rt_exit_critical();							    
}

void DelaymsByCount(uint16_t usDelayMS)
{
	uint16_t i;
	uint16_t j;
	for(j = 0; j < usDelayMS; j++)	
		for(i = 0; i < 8100; i++);	
}

void DelayusByCount(uint16_t usDelayUS)
{
	uint16_t	i;
	uint16_t j;
	for(j = 0; j < usDelayUS; j++)	
		for(i = 0; i < 81; i++);	
}

uint32_t GetElapsedSecs(void)
{
	return lo_unElapsedSecs;
}

uint32_t GetElapsedMSecs(void)
{
	return lo_unElapsedMSecs;
}

uint32_t GetCurSysticks(void)
{
	return lo_unCurSysticks;
}
